<?php namespace Connection;
use Workerman\Connection\ConnectionInterface;
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Connection\UdpConnection;
use Workerman\Events\EventInterface;

class UdpListenConnection extends ConnectionInterface {
    
    public function __construct($remote_address){  
        $socket = stream_socket_server("udp://".$remote_address, $errno, $errstr, STREAM_SERVER_BIND );
        $this->_remoteAddress = $remote_address;
        Worker::$globalEvent->add($socket, EventInterface::EV_READ, array($this, 'recvfrom'));
    }
 
    public function recvfrom($socket){
        $recv_buffer = stream_socket_recvfrom($socket, Worker::MAX_UDP_PACKAGE_SIZE, 0, $remote_address);
        if (false === $recv_buffer || empty($remote_address)) {
            return false;
        }  
        try {
            $connection = new \Workerman\Connection\UdpConnection($socket, $remote_address);
            $connection->protocol = $this->protocol;
            $recv_buffer = $this->protocol::decode($recv_buffer,$connection);
            call_user_func($this->onMessage, $connection, $recv_buffer); 
        // } catch (\Exception $e) {
        //     Worker::log($e);
        //     exit(250);
        // } catch (\Error $e) { 
        //     Worker::log($e);
        //     exit(250);
        } catch(\Throwable $e){
            echo $e; 
            exit(250);
        }
    }
  
    public function send($send_buffer){
        throw new Exception("Error Processing Request", 1); 
    }
    

    /**
     * Close connection.
     *
     * @param mixed $data
     * @param bool  $raw
     * @return bool
     */
    public function close($data = null, $raw = false)
    {
        if ($data !== null) {
            $this->send($data, $raw);
        }
        return true;
    }


    /**
     * Get remote IP.
     *
     * @return string
     */
    public function getRemoteIp()
    {
        $pos = strrpos($this->_remoteAddress, ':');
        if ($pos) {
            return trim(substr($this->_remoteAddress, 0, $pos), '[]');
        }
        return '';
    }

    /**
     * Get remote port.
     *
     * @return int
     */
    public function getRemotePort()
    {
        if ($this->_remoteAddress) {
            return (int)substr(strrchr($this->_remoteAddress, ':'), 1);
        }
        return 0;
    }

}